

// 每一个装饰器都是一个方法  

// new(...args :[]) : 约束构造的  : {}
function Controller (url){
  return function Controller<T extends {new(...args: any[]):{}}>(constructor: T){
    // 如果装饰的是类 
    constructor.prototype.a = 10;
    return class extends constructor{
      newProperty = 'hello'
      setName (){
        console.log(123)
      }
    }
  }
}

function log(params:{start:string,end:string}){
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor)
  {
    // target: 空的对象 key值 访问器属性的描述符
    // render方法本身 
    // 装饰器的原则 : 扩展
    const oldValue = descriptor.value
    descriptor.value = function (...rest:any[]){
      console.log(`${params.start}:${new Date().toLocaleDateString()}`)
      oldValue.apply(this,rest)
      console.log(`${params.end}:${new Date().toLocaleDateString()}`)
    }
    
  }
}

@Controller('/user')
export class Person{
  public ms = '' 
  constructor(ms:string){
    this.ms = ms
  }

  @log({start:'开始执行啦',end:'结束了'})
  render(a:string){
    console.log('lalalalal:'+a)
  }
}

new Person('12').render('hrihirhh')
console.log(new Person('12'))

// 装饰方法

// console.log(Person.setName())
// setTimeout(()=>{},20000000)